<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Chapter&nbsp;9.&nbsp;流程建模</title>
    <link rel="stylesheet" href="css/html.css" type="text/css">
    <meta name="generator" content="DocBook XSL Stylesheets V1.65.1">
    <link rel="home" href="index.html" title="JBoss jBPM 3.1">
    <link rel="up" href="index.html" title="JBoss jBPM 3.1">
    <link rel="previous" href="thejbpmdatabase.html" title="Chapter&nbsp;8.&nbsp;The jBPM Database">
    <link rel="next" href="context.html" title="Chapter&nbsp;10.&nbsp;Context">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
    <table width="100%" summary="Navigation header">
        <tr>
            <th colspan="3" align="center">Chapter&nbsp;9.&nbsp;流程建模</th>
        </tr>
        <tr>
            <td width="20%" align="left"><a accesskey="p" href="thejbpmdatabase.html">Prev</a>&nbsp;</td>
            <th width="60%" align="center">&nbsp;</th>
            <td width="20%" align="right">&nbsp;<a accesskey="n" href="context.html">Next</a></td>
        </tr>
    </table>
    <hr>
</div>
<div class="chapter" lang="en">
<div class="titlepage">
    <div>
        <div><h2 class="title"><a name="processmodelling"></a>Chapter&nbsp;9.&nbsp;流程建模</h2></div>
    </div>
    <div></div>
</div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="overview"></a>9.1.&nbsp;概览</h2></div>
        </div>
        <div></div>
    </div>
    <p>A process definition represents a formal specification of a business process and
        is based on a directed graph. The graph is composed of nodes and transitions. Every
        node in the graph is of a specific type. The type of the node defines the runtime
        behaviour. A process definition has exactly one start state.</p>

    <p>A token is one path of execution. A token is the runtime concept that maintains
        a pointer to a node in the graph.</p>

    <p>A process instance is one execution of a process definition. When a process instance
        is created, a token is created for the main path of execution. This token is called the
        root token of the process instance and it is positioned in the start state of the process
        definition.</p>

    <p>A signal instructs a token to continue graph execution. When receiving an unnamed
        signal, the token will leave its current node over the default leaving transition. When
        a transition-name is specified in the signal, the token will leave its node over the
        specified transition. A signal given to the process instance is delegated to the
        root token.</p>

    <p>After the token has entered a node, the node is executed. Nodes themselves are
        responsible for the continuation of the graph execution. Continuation of graph execution
        is done by making the token leave the node. Each node type can implement a different
        behaviour for the continuation of the graph execution. A node that does not propagate
        execution will behave as a state.</p>

    <p>Actions are pieces of java code that are executed upon events in the process
        execution. The graph is an important instrument in the communication about software
        requirements. But the graph is just one view (projection) of the software being produced.
        It hides many technical details. Actions are a mechanism to add technical details outside
        of the graphical representation. Once the graph is put in place, it can be decorated with
        actions. The main event types are entering a node, leaving a node and taking a
        transition.</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="processgraph"></a>9.2.&nbsp;流程图</h2></div>
        </div>
        <div></div>
    </div>
    <p>The basis of a process definition is a graph that is made up of nodes and transitions.
        That information is expressed in an xml file called <tt class="literal">processdefinition.xml</tt>.
        Each node has a type like e.g. state, decision, fork, join,... Each node has a set of leaving
        transitions. A name can be given to the transitions that leave a node in order to make them distinct.
        For example: The following diagram shows a process graph of the jBAY auction process.</p>

    <div class="figure"><a name="auction.process.graph.image"></a>

        <div class="mediaobject" align="center"><img src="images/auction.process.graph.gif" align="middle"
                                                     alt="The auction process graph"></div>
        <p class="title"><b>Figure&nbsp;9.1.&nbsp;The auction process graph</b></p></div>
    <p>Below is the process graph of the jBAY auction process represented as xml:</p><pre class="programlisting">&lt;process-definition&gt;

  &lt;start-state&gt;
    &lt;transition to="auction" /&gt;
  &lt;/start-state&gt;
  
  &lt;state name="auction"&gt;
    &lt;transition name="auction ends" to="salefork" /&gt;
    &lt;transition name="cancel" to="end" /&gt;
  &lt;/state&gt;
  
  &lt;fork name="salefork"&gt;
    &lt;transition name="shipping" to="send item" /&gt;
    &lt;transition name="billing" to="receive money" /&gt;
  &lt;/fork&gt;
  
  &lt;state name="send item"&gt;
    &lt;transition to="receive item" /&gt;
  &lt;/state&gt;

  &lt;state name="receive item"&gt;
    &lt;transition to="salejoin" /&gt;
  &lt;/state&gt;
  
  &lt;state name="receive money"&gt;
    &lt;transition to="send money" /&gt;
  &lt;/state&gt;

  &lt;state name="send money"&gt;
    &lt;transition to="salejoin" /&gt;
  &lt;/state&gt;
  
  &lt;join name="salejoin"&gt;
    &lt;transition to="end" /&gt;
  &lt;/join&gt;
  
  &lt;end-state name="end" /&gt;
  
&lt;/process-definition&gt;</pre>
</div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="nodes"></a>9.3.&nbsp;节点（Nodes）</h2></div>
        </div>
        <div></div>
    </div>
    <p>A process graph is made up of nodes and transitions. For more information about the
        graph and its executional model, refer to <a href="graphorientedprogramming.html"
                                                     title="Chapter&nbsp;4.&nbsp;Graph Oriented Programming">Chapter&nbsp;4,
        <i>Graph Oriented Programming</i></a>.
    </p>

    <p>Each node has a specific type. The node type determines what will happen when
        an execution arrives in the node at runtime. jBPM has a set of preimplemented node types
        that you can use. Alternatively, you can write custom code for implementing your own specific
        node behaviour.</p>

    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="noderesponsibilities"></a>9.3.1.&nbsp;Node responsibilities</h3></div>
            </div>
            <div></div>
        </div>
        <p>Each node has 2 main responsibilities: First, it can execute plain java code.
            Typically the plain java code relates to the function of the node. E.g. creating a
            few task instances, sending a notification, updating a database,... Secondly, a node
            is responsible for propagating the process execution. Basically, each node has the
            following options for propagating the process execution:</p>

        <div class="itemizedlist">
            <ul type="disc">
                <li><span class="bold"><b>1. not propagate the execution.</b></span> In that
                    case the node behaves as a wait state.
                </li>
                <li><span class="bold"><b>2. propagate the execution over one of the leaving
                    transitions of the node.</b></span> This means that the token that originally
                    arrived in the node is passed over one of the leaving transitions with the API call
                    executionContext.leaveNode(String). The node will now act as an automatic node in the
                    sense it can execute some custom programming logic and then continue process execution
                    automatically without waiting.
                </li>
                <li><span class="bold"><b>3. create new paths of execution.</b></span> A node can
                    decide to create new tokens. Each new token represents a new path of execution and
                    each new token can be launched over the node's leaving transitions. A good example of
                    this kind of behaviour is the fork node.
                </li>
                <li><span class="bold"><b>4. end paths of execution.</b></span> A node can decide
                    to end a path of execution. That means that the token is ended and the path of execution
                    is finished.
                </li>
                <li><span class="bold"><b>5. more general, a node can modify the whole runtime
                    structure of the process instance.</b></span> The runtime structure is a process instance
                    that contains a tree of tokens. Each token represents a path of execution. A node can
                    create and end tokens, put each token in a node of the graph and launch tokens over
                    transitions.
                </li>
            </ul>
        </div>
        <p>jBPM contains --as any workflow and BPM engine-- a set of preimplemented node types
            that have a specific documented configuration and behaviour. But the unique thing about
            jBPM and the <a href="graphorientedprogramming.html"
                            title="Chapter&nbsp;4.&nbsp;Graph Oriented Programming">Graph Oriented Programming
            foundation</a>
            is that we open up the model for developers. Developers can write their own node behaviour
            very easy and use it in a process.
        </p>

        <p>That is where traditional workflow and BPM systems are
            much more closed. They usually supply a fixed set of node types (called the process language).
            Their process language is closed and the executional model is hidden in the runtime
            environment. Research of <a href="http://www.workflowpatterns.com" target="_top">workflow patterns</a>
            has shown that any process language is not powerfull enough. We have decided for a simple
            model and allow developers to write their own node types. That way the JPDL process language
            is open ended.</p>

        <p>Next, we discuss the most important node types of JPDL.</p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypetasknode"></a>9.3.2.&nbsp;Nodetype task-node</h3></div>
            </div>
            <div></div>
        </div>
        <p>A task node represents one or more tasks that are to be performed by humans.
            So when execution arrives in a task node, task instances will be created in the task
            lists of the workflow participants. After that, the node will behave as a wait state.
            So when the users perform their task, the task completion will trigger the resuming
            of the execution. In other words, that leads to a new signal being called on the token.
        </p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypetaskstate"></a>9.3.3.&nbsp;Nodetype state</h3></div>
            </div>
            <div></div>
        </div>
        <p>A state is a bare-bones wait state. The difference with a task node is that
            no task instances will be created in any task list. This can be usefull if the process
            should wait for an external system. E.g. upon entry of the node (via an action on the node-enter
            event), a message could be sent to the external system. After that, the process will
            go into a wait state. When the external system send a response message, this can lead to
            a token.signal(), which triggers resuming of the process execution.</p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypedecision"></a>9.3.4.&nbsp;Nodetype decision</h3></div>
            </div>
            <div></div>
        </div>
        <p>Actually there are 2 ways to model a decision. The distinction between the two
            is based on *who* is making the decision. Should the decision made by the process (read:
            specified in the process definition). Or should an external entity provide the result of
            the decision.</p>

        <p>When the decision is to be taken by the process, a decision node should be used.
            There are basically 2 ways to specify the decision criteria. Simplest is by adding
            condition elements on the transitions. Conditions are beanshell script expressions that
            return a boolean. At runtime the decision node will loop over its leaving transitions (in
            the order as specified in the xml), and evaluate each condition. The first transition for
            which the conditions resolves to 'true' will be taken. Alternatively, an implementation
            of the DecisionHandler can be specified. Then the decision is calculated in a java class
            and the selected leaving transition is returned by the decide-method of the DecisionHandler
            implementation.</p>

        <p>When the decision is taken by an external party (meaning: not part of the process
            definition), you should use multiple transitions leaving a state or wait state node.
            Then the leaving transition can be provided in the external trigger that resumes execution
            after the wait state is finished. E.g. <tt class="literal">Token.signal(String transitionName)</tt>
            and <tt class="literal">TaskInstance.end(String transitionName)</tt>.
        </p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypefork"></a>9.3.5.&nbsp;Nodetype fork</h3></div>
            </div>
            <div></div>
        </div>
        <p>A fork splits one path of execution into multiple concurrent paths of execution. The
            default fork behaviour is to create a child token for each transition that leaves the fork,
            creating a parent-child relation between the token that arrives in the fork.</p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypejoin"></a>9.3.6.&nbsp;Nodetype join</h3></div>
            </div>
            <div></div>
        </div>
        <p>The default join assumes that all tokens that arrive in the join are children of the
            same parent. This situation is created when using the fork as mentioned above and when all
            tokens created by a fork arrive in the same join. A join will end every token that enters the
            join. Then the join will examine the parent-child relation of the token that enters the
            join. When all sibling tokens have arrived in the join, the parent token will be propagated
            over the (unique!) leaving transition. When there are still sibling tokens active, the join
            will behave as a wait state.</p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="nodetypenode"></a>9.3.7.&nbsp;Nodetype node</h3></div>
            </div>
            <div></div>
        </div>
        <p>The type node serves the situation where you want to write your own code in a node.
            The nodetype node expects one subelement action. The action is executed when the execution
            arrives in the node. The code you write in the actionhandler can do anything you want but
            it is also <a href="processmodelling.html#noderesponsibilities" title="9.3.1.&nbsp;Node responsibilities">responsible
            for propagating the execution</a>.
        </p>

        <p>This node can be used if you want to use a JavaAPI to implement some functional logic that
            is important for the business analyst. By using a node, the node is visible in the graphical
            representation of the process. For comparison, actions --covered next-- will allow you to
            add code that is invisible in the graphical representation of the process, in case that logic
            is not important for the business analyst.
        </p></div>
</div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="transitions"></a>9.4.&nbsp;跃迁（Transitions）</h2></div>
        </div>
        <div></div>
    </div>
    <p>Transitions have a source node and a destination node. The source node is represented with
        the property <tt class="literal">from</tt> and the destination node is represented by the property
        <tt class="literal">to</tt>.
    </p>

    <p>A node can optionally have a name. Note that most of the jBPM features depend on the uniqueness
        of the transition name. If more then one transition has the same name, the first transition with
        the given name is taken. In case duplicate transition names occur in a node, the method
        <tt class="literal">Map getLeavingTransitionsMap()</tt> will return less elements then
        <tt class="literal">List getLeavingTransitions()</tt>.
    </p>

    <p>The default transition is the first transition in the list.
    </p></div>
<div class="section" lang="en">
<div class="titlepage">
    <div>
        <div><h2 class="title" style="clear: both"><a name="actions"></a>9.5.&nbsp;动作（Actions）</h2></div>
    </div>
    <div></div>
</div>
<p>Actions are pieces of java code that are executed upon events in the process
    execution. The graph is an important instrument in the communication about software
    requirements. But the graph is just one view (projection) of the software being produced.
    It hides many technical details. Actions are a mechanism to add technical details outside
    of the graphical representation. Once the graph is put in place, it can be decorated with
    actions. This means that java code can be associated with the graph without changing the
    structure of the graph. The main event types are entering a node, leaving a node and taking a
    transition.</p>

<p>Note the difference between an action that is placed in an event versus an action
    that is placed in a node. Actions that are put in an event are executed when the event
    fires. Actions on events have no way to influence the flow of control of the process.
    It is similar to the observer pattern. On the other hand, an action that is put on a
    <a href="processmodelling.html#nodetypenode" title="9.3.7.&nbsp;Nodetype node">node</a> has the <a
        href="processmodelling.html#noderesponsibilities" title="9.3.1.&nbsp;Node responsibilities">responsibility
    of propagating the execution</a>.</p>

<p>Let's look at an example of an action on an event. Suppose we want to do a database
    update on a given transition. The database update is technically vital but it is not important
    to the business analyst.</p>

<div class="figure"><a name="database.update.example.image"></a>

    <div class="mediaobject" align="center"><img src="images/database.update.example.gif" align="middle"
                                                 alt="A database update action"></div>
    <p class="title"><b>Figure&nbsp;9.2.&nbsp;A database update action</b></p></div><pre class="programlisting">public class RemoveEmployeeUpdate implements ActionHandler {
  public void execute(ExecutionContext ctx) throws Exception {
    // get the fired employee from the process variables.
    String firedEmployee = (String) ctx.getContextInstance().getVariable("fired employee");
    
    // by taking the same database connection as used for the jbpm updates, we 
    // reuse the jbpm transaction for our database update.
    Connection connection = ctx.getProcessInstance().getJbpmSession().getSession().getConnection();
    Statement statement = connection.createStatement();
    statement.execute("DELETE FROM EMPLOYEE WHERE ...");
    statement.execute(); 
    statement.close();
  }
}</pre><pre class="programlisting">&lt;process-definition name="yearly evaluation"&gt;

  ...
  &lt;state name="fire employee"&gt;
    &lt;transition to="collect badge"&gt;
      &lt;action class="com.nomercy.hr.RemoveEmployeeUpdate" /&gt;
    &lt;/transition&gt;
  &lt;/state&gt;
  
  &lt;state name="collect badge"&gt;
  ...
  
&lt;/process-definition&gt;</pre>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h3 class="title"><a name="actionconfiguration"></a>9.5.1.&nbsp;Action configuration</h3></div>
        </div>
        <div></div>
    </div>
    <p>For more information about adding configurations to your custom actions and how
        to specify the configuration in the <tt class="literal">processdefinition.xml</tt>,
        see <a href="jpdl.html#configurationofdelegations" title="16.2.3.&nbsp;Configuration of delegations">Section&nbsp;16.2.3,
        &#8220;Configuration of delegations&#8221;</a>
    </p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h3 class="title"><a name="actionreferences"></a>9.5.2.&nbsp;Action references</h3></div>
        </div>
        <div></div>
    </div>
    <p>Actions can be given a name. Named actions can be referenced from other
        locations where actions can be specified. Named actions can also be put as child
        elements in the process definition.</p>

    <p>This feature is interesting if you want to limit duplication of action
        configurations (e.g. when the action has complicated configurations). Another
        use case is execution or scheduling of runtime actions.</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h3 class="title"><a name="events"></a>9.5.3.&nbsp;Events</h3></div>
        </div>
        <div></div>
    </div>
    <p>Events specify moments in the execution of the process. The jBPM engine
        will fire events during graph execution. This occurs when jbpm calculats the
        next state (read: processing a signal). An event is always relative to an element
        in the process definition like e.g. the process definition, a node or a transition.
        Most process elements can fire different types of events. A node for example can
        fire a <tt class="literal">node-enter</tt> event and a <tt class="literal">node-leave</tt>
        event. Events are the hooks for actions. Each event has a list of actions.
        When the jBPM engine fires an event, the list of actions is executed.</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h3 class="title"><a name="eventpropagation"></a>9.5.4.&nbsp;Event propagation</h3></div>
        </div>
        <div></div>
    </div>
    <p>Superstates create a parent-child relation in the elements of a process definition.
        Nodes and transitions contained in a superstate have that superstate as a parent. Top level
        elements have the process definition as a parent. The process definition does not have a
        parent. When an event is fired, the event will be propagated up the parent hierarchy.
        This allows e.g. to capture all transition events in a process and associate actions
        with these events in a centralized location.</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h3 class="title"><a name="script"></a>9.5.5.&nbsp;Script</h3></div>
        </div>
        <div></div>
    </div>
    <p>A script is an action that executes a beanshell script. For more information about beanshell,
        see <a href="http://www.beanshell.org/" target="_top">the beanshell website</a>.
        By default, all process variables are available as script-variables and no script-variables will be
        written to the process variables. Also the following script-variables will be available :
    </p>

    <div class="itemizedlist">
        <ul type="disc">
            <li>executionContext</li>
            <li>token</li>
            <li>node</li>
            <li>task</li>
            <li>taskInstance</li>
        </ul>
    </div><pre class="programlisting">&lt;process-definition&gt;
  &lt;event type="node-enter"&gt;
    &lt;script&gt;
      System.out.println("this script is entering node "+node);
    &lt;/script&gt;
  &lt;/event&gt;
  ...
&lt;/process-definition&gt;</pre>
    <p>To customize the default behaviour of loading and storing variables into the script, the
        <tt class="literal">variable</tt> element can be used as a sub-element of script. In that case,
        the script expression also has to be put in a subelement of script: <tt class="literal">expression</tt>.
    </p><pre class="programlisting">&lt;process-definition&gt;
  &lt;event type="process-end"&gt;
    &lt;script&gt;
      &lt;expression&gt;
        a = b + c;
      &lt;/expression&gt;
      &lt;variable name='XXX' access='write' mapped-name='a' /&gt;
      &lt;variable name='YYY' access='read' mapped-name='b' /&gt;
      &lt;variable name='ZZZ' access='read' mapped-name='c' /&gt;
    &lt;/script&gt;
  &lt;/event&gt;
  ...
&lt;/process-definition&gt;</pre>
    <p>Before the script starts, the process variables <tt class="literal">YYY</tt> and
        <tt class="literal">ZZZ</tt> will be made available to the script as script-variables
        <tt class="literal">b</tt> and <tt class="literal">c</tt> respectively. After the script is
        finished, the value of script-variable <tt class="literal">a</tt> is stored into the
        process variable <tt class="literal">XXX</tt>.</p>

    <p>If the <tt class="literal">access</tt> attribute of <tt class="literal">variable</tt> contains
        '<tt class="literal">read</tt>', the
        process variable will be loaded as a script-variable before script evaluation. If the
        <tt class="literal">access</tt> attribute contains '<tt class="literal">write</tt>', the script-variable
        will be stored as a process variable after evaluation.
        The attribute <tt class="literal">mapped-name</tt> can make the process variable available under another
        name in the script. This can be handy when your process variable names contain spaces or other
        invalid script-literal-characters.
    </p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h3 class="title"><a name="customevents"></a>9.5.6.&nbsp;Custom events</h3></div>
        </div>
        <div></div>
    </div>
    <p>Note that it's possible to fire your own custom events at will during the
        execution of a process. Events are uniquely defined by the combination of a graph
        element (nodes, transitions, process definitions and superstates are graph elements)
        and an event-type (java.lang.String). jBPM defines a set of events that are fired for
        nodes, transitions and other graph elements. But as a user, you are free to fire your
        own events. In actions, in your own custom node implementations, or even outside the execution
        of a process instance, you can call the <tt class="literal">GraphElement.fireEvent(String eventType,
        ExecutionContext executionContext);</tt>. The names of the event types can
        be chosen freely.
    </p></div>
</div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="superstates"></a>9.6.&nbsp;超级状态（Superstates）</h2></div>
        </div>
        <div></div>
    </div>
    <p>A Superstate is a group of nodes. Superstates can be nested recursively. Superstates
        can be used to bring some hierarchy in the process definition. For example, one application
        could be to group all the nodes of a process in phases. Actions can be associated with
        superstate events. A consequence is that a token can be in multiple nested nodes at a given
        time. This can be convenient to check wether a process execution is e.g. in the start-up phase.
        In the jBPM model, you are free to group any set of nodes in a superstate.
    </p>

    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="superstatetransitions"></a>9.6.1.&nbsp;Superstate transitions</h3></div>
            </div>
            <div></div>
        </div>
        <p>All transitions leaving a superstate can be taken by tokens in nodes contained within
            the super state. Transitions can also arrive in superstates. In that case, the token will be
            redirected to the first node in the superstate. Nodes from outside the superstate can have
            transitions directly to nodes inside the superstate. Also, the other way round, nodes within
            superstates can have transitions to nodes outside the superstate or to the superstate itself.
            Superstates also can have self references.</p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="superstateevents"></a>9.6.2.&nbsp;Superstate events</h3></div>
            </div>
            <div></div>
        </div>
        <p>There are 2 events unique to superstates: <tt class="literal">superstate-enter</tt> and
            <tt class="literal">superstate-leave</tt>. These events will be fired no matter over which
            transitions the node is entered or left respectively. As long as a token takes transitions
            within the superstate, these events are not fired.</p>

        <p>Note that we have created separate event types for states and superstates. This is
            to make it easy to distinct between superstate events and node events that are propagated
            from within the superstate.</p></div>
    <div class="section" lang="en">
        <div class="titlepage">
            <div>
                <div><h3 class="title"><a name="hierarchicalnames"></a>9.6.3.&nbsp;Hierarchical names</h3></div>
            </div>
            <div></div>
        </div>
        <p>Node names have to be unique in their scope. The scope of the node is its node-collection.
            Both the process definintion and the superstate are node collections. To refer to nodes in
            superstates, you have to specify the relative, slash (/) separated name. The slash separates
            the node names. Use '..' to refer to an upper level. The next example shows how to reference
            a node in a superstate:</p><pre class="programlisting">&lt;process-definition&gt;
  ...
  &lt;state name="preparation"&gt;
    &lt;transition to="phase one/invite murphy"/&gt;
  &lt;/state&gt;
  &lt;super-state name="phase one"&gt;
    &lt;state name="invite murphy"/&gt;
  &lt;/super-state&gt;
  ...
&lt;/process-definition&gt;</pre>
        <p>The next example will show how to go up the superstate hierarchy</p><pre class="programlisting">&lt;process-definition&gt;
  ...
  &lt;super-state name="phase one"&gt;
    &lt;state name="preparation"&gt;
      &lt;transition to="../phase two/invite murphy"/&gt;
    &lt;/state&gt;
  &lt;/super-state&gt;
  &lt;super-state name="phase two"&gt;
    &lt;state name="invite murphy"/&gt;
  &lt;/super-state&gt;
  ...
&lt;/process-definition&gt;</pre>
    </div>
</div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="exceptionhandling"></a>9.7.&nbsp;例外处理（Exception handling）</h2>
            </div>
        </div>
        <div></div>
    </div>
    <p>The exception handling mechanism of jBPM only applies to java exceptions.
        Graph execution on itself cannot result in problems. It is only the execution
        of delegation classes that can lead to exceptions.
    </p>

    <p>On <tt class="literal">process-definition</tt>s, <tt class="literal">node</tt>s and
        <tt class="literal">transition</tt>s, a list of <tt class="literal">exception-handler</tt>s
        can be specified. Each <tt class="literal">exception-handler</tt> has a list of actions.
        When an exception occurs in a delegation class, the process
        element parent hierarchy is serached for an appropriate <tt class="literal">exception-handler</tt>.
        When it is found, the actions of the <tt class="literal">exception-handler</tt> are
        executed.
    </p>

    <p>Note that the exception handling mechanism of jBPM is not completely similar to
        the java exception handling. In java, a caught exception can have an influence on
        the control flow. In the case of jBPM, control flow cannot be changed by the
        jBPM exception handling mechanism. The exception is either caught or uncaught.
        Uncaught exceptions are thrown to the client (e.g. the client that called the
        <tt class="literal">token.signal()</tt>) or the exception is caught by a jBPM
        <tt class="literal">exception-handler</tt>. For caught exceptions, the graph execution
        continues as if no exception has occurred.</p>

    <p>Note that in an <tt class="literal">action</tt> that handles an exception, it
        is possible to put the token in an arbitrary node in the graph with
        <tt class="literal">Token.setNode(Node node)</tt>.
    </p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="processcomposition"></a>9.8.&nbsp;流程组合（Process composition）
            </h2></div>
        </div>
        <div></div>
    </div>
    <p>Process composition is supported in jBPM by means of the <tt class="literal">process-state</tt>.
        The process state is a state that is associated with another process definition. When graph
        execution arrives in the process state, a new process instance of the sub-process is created
        and it is associated with the path of execution that arrived in the process state. The
        path of execution of the super process will wait till the sub process instance has ended.
        When the sub process instance ends, the path of execution of the super process will leave
        the process state and continue graph execution in the super process.
    </p><pre class="programlisting">&lt;process-definition name="hire"&gt;
  &lt;start-state&gt;
    &lt;transition to="initial interview" /&gt;
  &lt;/start-state&gt;
  &lt;process-state name="initial interview"&gt;
    &lt;sub-process name="interview" /&gt;
    &lt;variable name="a" access="read,write" mapped-name="aa" /&gt;
    &lt;variable name="b" access="read" mapped-name="bb" /&gt;
    &lt;transition to="..." /&gt;
  &lt;/process-state&gt;
  ...
&lt;/process-definition&gt;</pre>
    <p>This 'hire' process contains a <tt class="literal">process-state</tt>
        that spawns an 'interview' process. When execution arrives in the
        'first interview', a new execution (=process instance) for the latest
        version of the 'interview' process is created. Then variable 'a' from
        the hire process is copied into variable 'aa' from the interview process.
        The same way, hire variable 'b' is copied into interview variable 'bb'.
        When the interview process finishes, only variable 'aa' from the
        interview process is copied back into the 'a' variable of the
        hire process.</p>

    <p>In general, When a subprocess is started, all <tt class="literal">variable</tt>s with
        <tt class="literal">read</tt>
        access are read from the super process and fed into the newly created sub process before the signal
        is given to leave the start state. When the sub process instances is finished, all the
        <tt class="literal">variable</tt>s with <tt class="literal">write</tt> access will be copied from the sub
        process to the super process. The <tt class="literal">mapped-name</tt> attribute of the <tt class="literal">variable</tt>
        element allows you to specify the variable name that should be used in the sub process.</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="customnodebehaviour"></a>9.9.&nbsp;定制节点行为
            </h2></div>
        </div>
        <div></div>
    </div>
    <p>In jBPM, it's quite easy to write your own custom nodes. For creating custom nodes, an
        implementation of the ActionHandler has to be written. The implementation can execute any
        business logic, but also has the responsibility to propagate the graph execution. Let's look
        at an example that will update an ERP-system. We'll read an amout from the ERP-system, add
        an amount that is stored in the process variables and store the result back in the ERP-system.
        Based on the size of the amount, we have to leave the node via the 'small amounts' or the
        'large amounts' transition.
    </p>

    <div class="figure"><a name="update.erp.example.image"></a>

        <div class="mediaobject" align="center"><img src="images/update.erp.example.gif" align="middle"
                                                     alt="The update erp example process snippet"></div>
        <p class="title"><b>Figure&nbsp;9.3.&nbsp;The update erp example process snippet</b></p></div><pre
        class="programlisting">public class AmountUpdate implements ActionHandler {
  public void execute(ExecutionContext ctx) throws Exception {
    // business logic
    Float erpAmount = ...get amount from erp-system...;
    Float processAmount = (Float) ctx.getContextInstance().getVariable("amount");
    float result = erpAmount.floatValue() + processAmount.floatValue();
    ...update erp-system with the result...;
    
    // graph execution propagation
    if (result &gt; 5000) {
      ctx.leaveNode(ctx, "big amounts");
    } else {
      ctx.leaveNode(ctx, "small amounts");
    }
  }
}</pre>
    <p>It is also possible to create and join tokens in custom node
        implementations. For an example on how to do this, check out the Fork and
        Join node implementation in the jbpm source code :-).</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="graphexecution"></a>9.10.&nbsp;图的执行（Graph execution）</h2>
            </div>
        </div>
        <div></div>
    </div>
    <p>The graph execution model of jBPM is based on interpretation of the
        process definition and the chain of command pattern.</p>

    <p>Interpretation of the process definition means that the process
        definition data is stored in the database. At runtime the process definition
        information is used during process execution. Note for the concerned :
        we use hibernate's second level cache to avoid loading of definition information
        at runtime. Since the process definitions don't change (see process versioning)
        hibernate can cache the process definitions in memory.</p>

    <p>The chain of command pattern means that each node in the graph is
        responsible for propagating the process execution. If a node does not
        propagate execution, it behaves as a wait state.</p>

    <p>The idea is to start execution on process instances and that the execution
        continues till it enters a wait state.</p>

    <p>A token represents a path of execution. A token has a pointer to a node
        in the process graph. During waitstates, the tokens can be persisted
        in the database. Now we are going to look at the algorithm for calculating the
        execution of a token. Execution starts when a signal is sent to a token.
        The execution is then passed over the transitions and nodes via the chain of
        command pattern. These are the relevant methods in a class diagram.</p>

    <div class="figure"><a name="graph.execution.image"></a>

        <div class="mediaobject" align="center"><img src="images/graph.execution.gif" align="middle"
                                                     alt="The graph execution related methods"></div>
        <p class="title"><b>Figure&nbsp;9.4.&nbsp;The graph execution related methods</b></p></div>
    <p>When a token is in a node, signals can be sent to the token. Sending a
        signal is an instruction to start execution. A signal must therefore specify
        a leaving transition of the token's current node. The first transition is the
        default. In a signal to a token, the token takes its current node
        and calls the <tt class="literal">Node.leave(ExecutionContext,Transition)</tt> method. Think
        of the ExecutionContext as a Token because the main object in an ExecutionContext
        is a Token. The <tt class="literal">Node.leave(ExecutionContext,Transition)</tt> method will
        fire the <tt class="literal">node-leave</tt> event and call the
        <tt class="literal">Transition.take(ExecutionContext)</tt>. That method will fire
        the <tt class="literal">transition</tt> event and call the
        <tt class="literal">Node.enter(ExecutionContext)</tt> on the destination node of the
        transition. That method will fire the <tt class="literal">node-enter</tt> event and
        call the <tt class="literal">Node.execute(ExecutionContext)</tt>. Each type of node
        has its own behaviour that is implementated in the execute method. Each node
        is responsible for propagating graph execution by calling the
        <tt class="literal">Node.leave(ExecutionContext,Transition)</tt> again. In summary:</p>

    <div class="itemizedlist">
        <ul type="disc">
            <li>Token.signal(Transition)</li>
            <li>--&gt; Node.leave(ExecutionContext,Transition)</li>
            <li>--&gt; Transition.take(ExecutionContext)</li>
            <li>--&gt; Node.enter(ExecutionContext)</li>
            <li>--&gt; Node.execute(ExecutionContext)</li>
        </ul>
    </div>
    <p>Note that the complete calculation of the next state, including the invocation
        of the actions is done in the thread of the client. A common misconception is that
        all calculations *must* be done in the thread of the client. As with any asynchronous
        invocation, you can use asynchronous messaging (JMS) for that. When the message is
        sent in the same transaction as the process instance update, all synchronization issues
        are taken care of. Some workflow systems use asynchronous messaging between all nodes
        in the graph. But in high throughput environments, this algorithm gives much more control
        and flexibility for tweaking performance of a business process.</p></div>
<div class="section" lang="en">
    <div class="titlepage">
        <div>
            <div><h2 class="title" style="clear: both"><a name="transactiondemarcation"></a>9.11.&nbsp;事务界线（Transaction
                demarcation）</h2></div>
        </div>
        <div></div>
    </div>
    <p>As explained in <a href="processmodelling.html#graphexecution" title="9.10.&nbsp;Graph execution">Section&nbsp;9.10,
        &#8220;Graph execution&#8221;</a> and
        <a href="graphorientedprogramming.html" title="Chapter&nbsp;4.&nbsp;Graph Oriented Programming">Chapter&nbsp;4,
            <i>Graph Oriented Programming</i></a>, jBPM runs the process in the thread of
        the client and is by nature synchronous. Meaning that the <tt class="literal">token.signal()</tt>
        or <tt class="literal">taskInstance.end()</tt> will only return when the process has entered a new
        wait state.
    </p>

    <p>The jPDL feature that we describe here from a modelling perspective is
        <a href="asynchronouscontinuations.html" title="Chapter&nbsp;13.&nbsp;Asynchronous continuations">Chapter&nbsp;13,
            <i>Asynchronous continuations</i></a>.
    </p>

    <p>In most situations this is the most straightforward approach because the process
        execution can easily be bound to server side transactions: the process moves from one
        state to the next in one transaction.
    </p>

    <p>In some scenarios where in-process calculations take a lot of time, this behaviour
        might be undesirable. To cope with this, jBPM includes an asynchronous messaging system
        that allows to continue a process in an asynchronous manner. Of course, in a java enterprise
        environment, jBPM can be configured to use a JMS message broker instead of the built in
        messaging system.
    </p>

    <p>In any node, jPDL supports the attribute <tt class="literal">async="true"</tt>.
        Asynchronous nodes will not be executed in the thread of the client. Instead, a message is
        sent over the asynschronous messaging system and the thread is returned to the client
        (meaning that the <tt class="literal">token.signal()</tt> or <tt class="literal">taskInstance.end()</tt>
        will return).
    </p>

    <p>Note that the jbpm client code can now commit the transaction. The sending of the
        message should be done in the same transaction as the process updates. So the net result of
        the transaction is that the token has moved to the next node (which has not yet been executed)
        and a <tt class="literal">org.jbpm.command.ExecuteNodeCommand</tt>-message has been sent on the
        asynchronous messaging system to the jBPM Command Executor.
    </p>

    <p>The jBPM Command Executor reads commands from the queue and executes them. In the case
        of the <tt class="literal">org.jbpm.command.ExecuteNodeCommand</tt>, the process will be continued
        with executing the node. Each command is executed in a separate transaction.
    </p>

    <p>So in order for asynchronous processes to continue, a jBPM Command Executor needs to
        be running. The simplest way to do that is to configure the <tt class="literal">CommandExecutionServlet</tt>
        in your web application. Alternatively, you should make sure that the CommandExecutor thread is
        up and running in any other way.
    </p>

    <p>As a process modeller, you should not really be concerned with all this asynchronous
        messaging. The main point to remember is transaction demarcation: By default jBPM will operate
        in the transaction of the client, doing the whole calculation until the process enters a wait
        state. Use <tt class="literal">async="true"</tt> to demarcate a transaction in the process.
    </p>

    <p>Let's look at an example:
    </p><pre class="programlisting">...
&lt;start-state&gt;
  &lt;transition to="one" /&gt;
&lt;/start-state&gt;
&lt;node async="true" name="one"&gt;
  &lt;action class="com...MyAutomaticAction" /&gt;
  &lt;transition to="two" /&gt;
&lt;/node&gt;
&lt;node async="true" name="two"&gt;
  &lt;action class="com...MyAutomaticAction" /&gt;
  &lt;transition to="three" /&gt;
&lt;/node&gt;
&lt;node async="true" name="three"&gt;
  &lt;action class="com...MyAutomaticAction" /&gt;
  &lt;transition to="end" /&gt;
&lt;/node&gt;
&lt;end-state name="end" /&gt;
...</pre>
    <p>Client code to interact with process executions (starting and
        resuming) is exactly the same as with normal (synchronous) processes:
    </p><pre class="programlisting">...start a transaction...
JbpmContext jbpmContext = jbpmConfiguration.createContext();
try {
  ProcessInstance processInstance = jbpmContext.newProcessInstance("my async process");
  processInstance.signal();
  jbpmContext.save(processInstance);
} finally {
  jbpmContext.close();
}</pre>
    <p>After this first transaction, the root token of the process instance
        will point to node <tt class="literal">one</tt> and a
        <tt class="literal">ExecuteNodeCommand</tt>message will have been sent to the
        command executor.
    </p>

    <p>In a subsequent transaction, the command executor will read the message
        from the queue and execute node <tt class="literal">one</tt>. The action can decide to
        propagate the execution or enter a wait state. If the action decides to propagate
        the execution, the transaction will be ended when the execution arrives at
        node two. And so on, and so on...
    </p></div>
</div>
<div class="navfooter">
    <hr>
    <table width="100%" summary="Navigation footer">
        <tr>
            <td width="40%" align="left"><a accesskey="p" href="thejbpmdatabase.html">Prev</a>&nbsp;</td>
            <td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
            <td width="40%" align="right">&nbsp;<a accesskey="n" href="context.html">Next</a></td>
        </tr>
        <tr>
            <td width="40%" align="left" valign="top">Chapter&nbsp;8.&nbsp;The jBPM Database&nbsp;</td>
            <td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
            <td width="40%" align="right" valign="top">&nbsp;Chapter&nbsp;10.&nbsp;Context</td>
        </tr>
    </table>
</div>
</body>
</html>